﻿using Client.MirNetwork;
using Client.MirObjects;
using Client.MirScenes;
using Client.MirScenes.Dialogs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Client.Command
{
    class HangUpCmd
    {
        private object syncObj = new object();
        private PathFinderD pathFinder = null;
        public PathFinderD PathFinder
        {
            get{
                if(pathFinder==null)
                {
                    lock(syncObj)
                    {
                        if(pathFinder==null)
                        {
                        pathFinder= new PathFinderD(GameScene.Scene.MapControl);
                        }
                    }
                }
                return pathFinder;
            }
            set
            {
                pathFinder = value;
            }
        }
        public List<NodeD> CurrentPath = null;
        public bool HangUpPath = false;

        public void AutoMed(HangDialog hangDialog)
        {
            var User = GameScene.User;
            if (hangDialog.HpTime < CMain.Time)
            {
                hangDialog.HpTime = CMain.Time + 700;
                if(User.HP < hangDialog.RescueHp)
                {
                    if (!User.Dead)
                    {
                        UseMed(hangDialog.RescueIndex);
                        UseMed(hangDialog.HpIndex);
                    }
                    return;
                }
                if (User.HP < hangDialog.DangerHp)
                {
                    if (!User.Dead)
                    {
                        UseMed(hangDialog.HpIndex);
                        if (User.Class == MirClass.Taoist)
                        {
                            var magic = User.Magics.Find(a => a.Spell == Spell.Healing);
                            if (magic != null)
                                UseSkill(Spell.Healing, 1, (t) => true, User);
                        }
                    }
                }
            }
            if (hangDialog.MpTime < CMain.Time)
            {
                hangDialog.MpTime = CMain.Time + 1500;
                if (User.MP < hangDialog.DangerMp)
                {
                    if (!User.Dead)
                        UseMed(hangDialog.MpIndex);
                }
            }
        }
        public static bool IsValidTarget(MapObject target)
        {
            return target != null && !target.Dead;
                //&&target.PercentHealth>0;
        }

        public void AutoMagic()
        {
            var finished = UseSkill(Spell.SoulFireBall, 9, (target) =>
                    target is MonsterObject &&//是个怪物
                   !target.Dead);
        }
        public void AutoDrug()
        {
            

            var finished=UseSkill(Spell.Poisoning, 9, (target) =>
                 target is MonsterObject &&//是个怪物
                !target.Dead &&//怪物没死
                !target.Poison.HasFlag(PoisonType.Green)&&
                !target.Poison.HasFlag(PoisonType.Red) //身上有毒
            );

            //if (!finished)
            //{
            //    foreach (var pet in GameScene.User.Pets)
            //    {
            //        if(!pet.Dead||pet.)
            //    }
            //}
        }
        public void AutoAmore()
        {
            UserObject user = GameScene.User;
            if (user.Class == MirClass.Wizard)
            {
                var magic = user.Magics.Find(a => a.Spell == Spell.MagicShield);
                if (magic != null)
                    UseSkill(Spell.Healing, 1, (t) => !user.Buffs.Contains(BuffType.MagicShield), user);
            }
            if(user.Class==MirClass.Taoist)
            {
                bool finished = false;
                if (!finished)
                {
                    finished = UseSkill(Spell.BlessedArmour, 1, (target) =>
                            !GameScene.Scene.Buffs.Any(a => a.Type == BuffType.BlessedArmour));
                }
                if (!finished)
                {
                    finished = UseSkill(Spell.SoulShield, 1, (target) =>
                            !GameScene.Scene.Buffs.Any(a => a.Type == BuffType.SoulShield));
                }
                if(!finished)
                {
                    finished = UseSkill(Spell.UltimateEnhancer, 1, (target) =>
        !           GameScene.Scene.Buffs.Any(a => a.Type == BuffType.UltimateEnhancer), user);
                }

            }
        }

        public void AutoMine()
        {
            var Inventory = GameScene.User.Inventory;
            string[] dropArr = new String[] { "铜矿", "银矿", "铁矿" };
            var lj=Inventory.FirstOrDefault(a =>a!=null&&dropArr.Contains(a.Name));
            if(lj!=null)
                Network.Enqueue(new ClientPackets.DropItem { UniqueID = lj.UniqueID, Count = 1 });
        }
        public void AutoPractice()
        {

            var magic = GameScene.User.Magics.FirstOrDefault(a=>a.Key==8);

            if (magic == null) {
                MessageBox.Show("F8未绑定技能，无法练习");
                GameScene.Scene.HangDialog.AutoPractice = false;
                return;
            }
            switch (magic.Spell)
            {
                case Spell.SummonHolyDeva:
                case Spell.SummonShinsu:
                case Spell.SummonSkeleton:
                case Spell.SoulShield:
                case Spell.BlessedArmour:
                    UseSkill(magic.Spell, 1, (t) => true);
                    return;
                default:
                    GameScene.Scene.UseSpell(8);
                    break;
            }
        }
        private bool UseSkill(Spell skill,int range, Predicate<MapObject> preRequire,MapObject target=null)
        {
            var magic = GameScene.User.Magics.Find(a => a.Spell ==skill);
            if (null != magic)
            {
                target =target?? MapObject.TargetObject;
                if(preRequire?.Invoke(target)??false)
                {
                    switch (skill)
                    {
                        case Spell.HealingCircle:
                        case Spell.SoulFireBall:
                        case Spell.Hiding:
                        case Spell.MassHiding:
                        case Spell.TrapHexagon:
                        case Spell.Purification:
                        case Spell.SummonHolyDeva:
                        case Spell.SummonShinsu:
                        case Spell.SummonSkeleton:
                        case Spell.SoulShield:
                        case Spell.BlessedArmour:
                        case Spell.UltimateEnhancer:
                            if (!MirTool.FindAndChangeItem("护身符"))
                                return false;
                            break;
                        case Spell.Poisoning:
                            if (!MirTool.FindAndChangeItem("药粉"))
                                return false;
                            break;
                    }
                    switch(skill)
                    {
                        case Spell.SummonHolyDeva:
                        case Spell.SummonShinsu:
                        case Spell.SummonSkeleton:
                        case Spell.SoulShield:
                        case Spell.BlessedArmour:
                            GameScene.User.NextMagicLocation =GameScene.User.CurrentLocation.Subtract(new System.Drawing.Point(1,1));
                            GameScene.User.NextMagicObject = GameScene.User;
                            GameScene.User.NextMagicDirection = MirDirection.Up;
                            GameScene.User.NextMagic = magic;
                            return true;
                        default:
                            if (Functions.InRange(GameScene.User.CurrentLocation, target.CurrentLocation, range))
                            {
                                MapObject.MagicObject = MapObject.TargetObject;
                                GameScene.User.NextMagic = magic;
                                return true;
                            }
                            else
                            {
                                break;
                            }
                    }
                }
            }
            return false;
        }
        private void UseMed(int[] MedIndex)
        {
            var c1 = GameScene.Scene.InventoryDialog.Grid.FirstOrDefault(a => { if (a.Item != null) { return MedIndex.Contains(a.Item.ItemIndex); } return false; });
            if (c1 == null)
            {
                c1 = GameScene.Scene.BeltDialog.Grid.FirstOrDefault(a => { if (a.Item != null) { return MedIndex.Contains(a.Item.ItemIndex); } return false; });
            }
            if (c1 == null)
            {
                Console.WriteLine("没有找到药物");
            }
            else
            {
                c1.UseItem();
            }
        }
        private void AutoGoPath()
        {
            if (HangUpPath)
            {
                var User = GameScene.User;
                if (CurrentPath == null || CurrentPath.Count == 0)
                {
                    HangUpPath = false;
                    return;
                }

                NodeD currentNode = CurrentPath.SingleOrDefault(x => User.CurrentLocation == x.Location);
                if (currentNode != null)
                {
                    while (true)
                    {
                        NodeD first = CurrentPath.First();
                        CurrentPath.Remove(first);

                        if (first == currentNode)
                            break;
                    }
                }

                if (CurrentPath.Count > 0)
                {
                    MirDirection dir = Functions.DirectionFromPoint(User.CurrentLocation, CurrentPath.First().Location);
                    NodeD upcomingStep = CurrentPath.SingleOrDefault(x => Functions.PointMove(User.CurrentLocation, dir, 2) == x.Location);
                    //当不能走的时候，重新计算路径。
                    if (!GameScene.Scene.MapControl.CanWalk(dir))
                    {
                        var target = CurrentPath.Last();
                        PathFinder.UpdatePath(upcomingStep);
                        CurrentPath = pathFinder.RetracePath(upcomingStep, target).ToList();
#if DEBUG
                        Console.WriteLine("发现障碍物，重置路劲");
#endif
                        return;
                    }

                    if (GameScene.CanRun && GameScene.Scene.MapControl.CanRun(dir) && CMain.Time > GameScene.NextRunTime && User.HP >= 10 && CurrentPath.Count > 1 && upcomingStep != null)
                    {
                        User.QueuedAction = new QueuedAction { Action = MirAction.Running, Direction = dir, Location = Functions.PointMove(User.CurrentLocation, dir, 2) };
                        return;
                    }
                    if (GameScene.Scene.MapControl.CanWalk(dir))
                    {
                        User.QueuedAction = new QueuedAction { Action = MirAction.Walking, Direction = dir, Location = Functions.PointMove(User.CurrentLocation, dir, 1) };

                        //if (first == currentNode)
                        //    break;
                    }
                }

                if (CurrentPath.Count > 0)
                {
                    MirDirection dir = Functions.DirectionFromPoint(User.CurrentLocation, CurrentPath.First().Location);
                    NodeD upcomingStep = CurrentPath.SingleOrDefault(x => Functions.PointMove(User.CurrentLocation, dir, 2) == x.Location);
                    //当不能走的时候，重新计算路径。
                    if (!GameScene.Scene.MapControl.CanWalk(dir))
                    {
                        var target = CurrentPath.Last();
                        PathFinder.UpdatePath(upcomingStep);
                        CurrentPath = pathFinder.RetracePath(upcomingStep, target).ToList();
#if DEBUG
                        Console.WriteLine("发现障碍物，重置路劲");
#endif
                        return;
                    }

                    if (GameScene.CanRun && GameScene.Scene.MapControl.CanRun(dir) && CMain.Time > GameScene.NextRunTime && User.HP >= 10 && CurrentPath.Count > 1 && upcomingStep != null)
                    {
                        User.QueuedAction = new QueuedAction { Action = MirAction.Running, Direction = dir, Location = Functions.PointMove(User.CurrentLocation, dir, 2) };
                        return;
                    }
                    if (GameScene.Scene.MapControl.CanWalk(dir))
                    {
                        User.QueuedAction = new QueuedAction { Action = MirAction.Walking, Direction = dir, Location = Functions.PointMove(User.CurrentLocation, dir, 1) };

                        return;
                    }
                }
            }
        }


        internal void GoPath()
        {
            if (CurrentPath == null || CurrentPath.Count() == 0)
            {
                HangUpPath = false;
                return;
            }
            var User = GameScene.User;
            var currentLoaction = GameScene.User.CurrentLocation;
            NodeD currentNode = CurrentPath.SingleOrDefault(x => GameScene.User.CurrentLocation == x.Location);
            if(currentNode!=null)
            {
                while (true)
                {
                    NodeD first = CurrentPath.First();
                    CurrentPath.Remove(first);
                    if (first == currentNode)
                        break;
                }
            }

            if (CurrentPath.Count > 0)
            {
                MirDirection dir = Functions.DirectionFromPoint(currentLoaction, CurrentPath.First().Location);
                NodeD upcomingStep = CurrentPath.SingleOrDefault(x => Functions.PointMove(User.CurrentLocation, dir, 2) == x.Location);
                //当不能走的时候，重新计算路径。
                if (!GameScene.Scene.MapControl.CanWalk(dir))
                {
                    var target = CurrentPath.Last();
                    var start = CurrentPath.First().Parent;
                    PathFinder.UpdatePath(CurrentPath.First());
                    CurrentPath = PathFinder.RetracePath(start,target).ToList();
#if DEBUG
                    Console.WriteLine("发现障碍物，重置路劲");
#endif

                    return;
                }

                if (GameScene.CanRun && GameScene.Scene.MapControl.CanRun(dir) && CMain.Time > GameScene.NextRunTime && User.HP >= 10 && CurrentPath.Count > 1 && upcomingStep != null)
                {
                    User.QueuedAction = new QueuedAction { Action = MirAction.Running, Direction = dir, Location = Functions.PointMove(User.CurrentLocation, dir, 2) };
                    return;
                }
                if (GameScene.Scene.MapControl.CanWalk(dir))
                {
                    User.QueuedAction = new QueuedAction { Action = MirAction.Walking, Direction = dir, Location = Functions.PointMove(User.CurrentLocation, dir, 1) };
                    return;
                }
            }
        }
    }
   
}
